package encrypt;


import java.util.concurrent.atomic.AtomicInteger;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;

import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;

/** 
 * 密码重复次数限制，防止字典扫描攻击
 * 此模块未测试通过
 * @author Henry
 * 2019年4月17日
 */
public class RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher{

	private Ehcache passwordRetryCache;
	
	public RetryLimitHashedCredentialsMatcher(){
		CacheManager cacheManager= CacheManager.newInstance(CacheManager.class.getClassLoader().getResource("ehcache.xml"));
		passwordRetryCache= cacheManager.getCache("passwordRetryCache");	
		//System.out.println(passwordRetryCache.getName());
		//System.out.println(passwordRetryCache);
	}
	
	public boolean doCredentialsMatch(AuthenticationToken token,AuthenticationInfo info){
		String username= (String)token.getPrincipal();
		//System.out.println(username);
		Element element= passwordRetryCache.get(username);
		if(element==null){
			element= new Element(username,new AtomicInteger(0));
			passwordRetryCache.put(element);
		}
		AtomicInteger retryCount= (AtomicInteger)element.getObjectValue();
		if(retryCount.incrementAndGet()>5){
			System.out.println(retryCount);
			throw new ExcessiveAttemptsException();
		}
		boolean matches= super.doCredentialsMatch(token, info);
		if(matches){
			passwordRetryCache.remove(username);
		}
		return matches;
	}
	
	public static void main(String[] args) {
		//AtomicInteger a= new AtomicInteger(0);
		//System.out.println(a.getAndSet(1));
		//System.out.println(a.getAndSet(2));
		////System.out.println(a);
		//System.out.println(a.compareAndSet(0,4));
		//System.out.println(a);
		//Double z= 1.9;
		//System.out.println(z.intValue());
		Runtime r=Runtime.getRuntime();
		System.out.println(r.freeMemory());
		System.out.println(r.totalMemory());
		System.out.println(r.totalMemory());
		System.out.println(r.availableProcessors());
		r.gc();
	}
}
